﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

using RemoteScriptingLibrary;
using RemoteScriptingLibrary.Microsoft.Win32;

namespace WindowsRemoteScripting.Action
{
    public class MacroRecorderEvent
    {
        protected object m_oData = null;

        public MacroRecorderEvent()
        {
        }

        public MacroRecorderEvent(object _oData)
        {
            m_oData = _oData;
        }

        public object Data
        {
            get { return m_oData; }
            set { m_oData = value; }
        }

        public override string ToString()
        {
            return m_oData.ToString();
        }
    }

    public class MacroRecorder : AbstractCommand
    {
        public static Win32.LowLevelMouseProc _proc = HookCallback;
        private static bool m_bLeftButtonDown;
        protected static int m_nCount = 0;
        protected static List<MacroRecorderEvent> m_aMacroRecorderEvent = new List<MacroRecorderEvent>();

        protected Timer m_Timer = new Timer();

        protected int m_nTickInterval = 1000;

        public MacroRecorder()
        {
            m_Timer.Tick += new EventHandler(m_Timer_Tick);
            m_Timer.Interval = m_nTickInterval;
        }

        void m_Timer_Tick(object sender, EventArgs e)
        {
            Win32.POINT point = Helper.GetMouseCoordinates();
            string sText = string.Format("MouseMove({0}, {1})", point.X, point.Y);

            if (Form1.m_Form.chkbOptimize.Checked)
            {
                sText = string.Format("MouseMove({0}, {1}, {2}, {3})", point.X, point.Y, 100, 10);
            }

            m_aMacroRecorderEvent.Add(new MacroRecorderEvent(sText));
            if (Form1.m_Form.chkbInsertSleeps.Checked)
            {
                m_aMacroRecorderEvent.Add(new MacroRecorderEvent("Sleep(1000)"));
            }
            m_nCount++;
            Form1.m_Form.lbRecordedEvents.Text = m_nCount.ToString();
        }

        public void Stop()
        {
            m_Timer.Stop();
            foreach (MacroRecorderEvent macroRecorderEvent in m_aMacroRecorderEvent)
            {
                Form1.m_Form.textBox1.AppendText(macroRecorderEvent.ToString() + Environment.NewLine);
            }
        }

        public int TickInterval
        {
            get { return m_nTickInterval; }
            set { m_nTickInterval = value; }
        }

        public static IntPtr SetHook(Win32.LowLevelMouseProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return Win32.SetWindowsHookEx(Win32.WH_MOUSE_LL, proc,
                    Win32.GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private static IntPtr HookCallback(
            int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 &&
                Win32.MouseMessages.WM_LBUTTONUP == (Win32.MouseMessages)wParam)
            {
                m_bLeftButtonDown = false;
                Console.WriteLine(m_bLeftButtonDown);
                m_aMacroRecorderEvent.Add(new MacroRecorderEvent("MouseClick()"));
                m_nCount++;
            }

            if (nCode >= 0 &&
                Win32.MouseMessages.WM_LBUTTONDOWN == (Win32.MouseMessages)wParam)
            {
                m_bLeftButtonDown = true;
                Console.WriteLine(m_bLeftButtonDown);
            }
            return Win32.CallNextHookEx(Form1._hookID, nCode, wParam, lParam);
        }

        public override void Run(object sender, EventArgs e)
        {
            if (Form1.m_Form.chkbMacroRecorder.Checked)
            {
                m_Timer.Start();
            }
            else
            {
                Stop();
            }
        }
    }
}
